function [flat, tree] = flattenStruct(nested, flat, tree)
  % Flatten nested structure using recursion.
  % Only recurses to first non-struct on any given path; 
  % a struct in a cell array, for example, will not be flattened
  % (although one can of course run this again on such "missed" structures).
  % New field names preserve the tree-path information.
  %
  % Example:
  % level1_1 = struct('b', 2, 'c', 3);
  % level1_2 = struct('d', 4, 'e', 5);
  % level2_1 = struct('a', 1, 'A', level1_1);
  % level2_2 = struct('f', 6, 'B', level1_2);
  % level3   = struct('C', level2_1, 'D', level2_2);
  % level4   = struct('E', level3);
  % P        = level4;
  % [Q, ~] = flattenStruct(P, struct())
  % 
  % Outputs:
  % Q = 
  %         ECa: 1
  %        ECAb: 2
  %        ECAc: 3
  %         EDf: 6
  %        EDBd: 4
  %        EDBe: 5
  %
  % Author: David Goldsmith, Wash. State Dept. of Ecology, dgol461@ecy.wa.gov
  % Release date: 9/15/2011

    global nlm
    nlm = namelengthmax;
    if nargin < 3
        tree = {};
    end
    if nargin < 2
        flat = struct();
    end
    for n=nested{:}'
        while isstruct(n)
            for field=fieldnames(n)'
                f = char(field);
                tree{end+1} = f;
                [tmpflat, tmptree] = flattenStruct({n.(f)}, flat, tree);
                flat = tmpflat; tree = tmptree;
            end
            tree = tree(1:end-1);
            return
        end
        flatname = tree{1}; broke = 0;
        for i=2:length(tree)
            tmp = [flatname '_' tree{i}];
            if length(tmp) > nlm
                broke = 1;
                break
            else
                flatname = tmp;
            end
        end
        if broke
            ext = tree{i};
            for j=i+1:length(tree)
                ext = [ext '_' tree{j}];
            end    
            flat.(flatname).(ext) = n;
        else
            flat.(flatname) = n;
        end
    end
    
    tree = tree(1:end-1);
end